﻿using System;


/*
 流程如下：
    发布者发布事件
    事件发布后订阅者订阅事件的时候必须通过一个方法订阅（接收）发布者
    此时订阅者就已经能收到发布者发布的事件了
    订阅者收到发布的事件后就可以给事件添加处理器了（方法）
 */
//事件
namespace EventDemo {
    // 定义一个委托类型，用于事件处理程序
     public delegate void NotifyEventHandler(object sender, EventArgs e);

     // 发布者类
     public class ProcessBusinessLogic {
         // 声明事件
         public event NotifyEventHandler ProcessCompleted;

         // 触发事件的方法
         // virtual virtual 关键字用于在基类中声明一个方法、属性、索引器或事件，使其可以在派生类中被重写（override）。
         // 这提供了一种实现多态性的机制，允许不同的派生类提供基类中声明的成员的具体实现。
         protected virtual void OnProcessCompleted(EventArgs e) {
             //执行事件，这里的this指向的是 ProcessBusinessLogic 这个类，因为这个类是事件的发送者，需要传递给订阅者
             ProcessCompleted?.Invoke(this, e);
         }

         // 模拟业务逻辑过程并触发事件
         public void StartProcess() {
             Console.WriteLine("Process Started!");

             // 这里可以加入实际的业务逻辑

             // 业务逻辑完成，触发事件
             OnProcessCompleted(EventArgs.Empty);
         }
     }

     // 订阅者类
     public class EventSubscriber {
         public void Subscribe(ProcessBusinessLogic process) {
             //订阅  += 和 -= 运算符订阅和取消订阅事件，这是给事件添加事件处理器
             process.ProcessCompleted += Process_ProcessCompleted;
         }
         //事件处理程序
         private void Process_ProcessCompleted(object sender, EventArgs e) {
             Console.WriteLine("Process Completed!");
         }
     }

     class Program {
         static void Main(string[] args) {
             ProcessBusinessLogic process = new ProcessBusinessLogic();
             EventSubscriber subscriber = new EventSubscriber();

             /*这里的执行流程是：
              1、首先订阅事件，因为订阅事件后才能指定事件是否执行完成
              2、执行事件
              3、事件执行完成后通知的 订阅方，然后订阅方在进行执行
              */

             // 首先需要 订阅事件
             subscriber.Subscribe(process);

             // 启动过程
             process.StartProcess();



             Console.ReadLine();
        }
    }
}